package com.ac.scum.log.web.model.ftp.controller;

import com.ac.scum.log.bean.ServerFTP;
import com.ac.scum.log.web.config.LocalDateTimeAdapter;
import com.ac.scum.log.web.model.ftp.manager.FtpSessionManager;
import com.ac.scum.log.web.utils.ftp.FTPUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Component
@ServerEndpoint("/ftpCheck")
public class FtpWebSocketController {

    private final static Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter()).create();
    private final FtpSessionManager ftpSessionManager = new FtpSessionManager();

    @Data
    class FtpMessage {
        String action;
        String path;
        ServerFTP serverFTP;
        List<FTPFile> files;
        String message;
        String clickId;
    }


    public FtpMessage connectToFtp(Session session, FtpMessage ftpMessage) {
        FTPUtil ftpUtil = new FTPUtil(ftpMessage.getServerFTP());
        try {
            ftpUtil.connect();
            ftpSessionManager.addSessionFtpClient(session.getId(), ftpUtil);
            ftpMessage.setPath(StringUtils.isBlank(ftpMessage.getPath()) ? "/" : ftpMessage.getPath());
            return handleFtpCd(session, ftpMessage);
        } catch (Exception e) {
            ftpMessage.setMessage("Failed to connect to FTP server M: " + e.getMessage());
            return ftpMessage;
        }
    }


    public FtpMessage handleFtpCd(Session session, FtpMessage ftpMessage) {
        FTPUtil ftpUtil = ftpSessionManager.getSessionFtpClient(session.getId());
        if (!ftpUtil.isConnected()) {
            ftpMessage.setMessage("Not connected to FTP server");
            return ftpMessage;
        }

        try {
            List<FTPFile> ftpFiles = ftpUtil.listFiles(ftpMessage.getPath());
            ftpMessage.setFiles(ftpFiles);
            ftpMessage.setMessage("ok");
            return ftpMessage;
        } catch (Exception e) {
            ftpMessage.setMessage("Error executing command: " + e.getMessage());
            return ftpMessage;
        }
    }

    @OnMessage
    public String onMsg(Session session, String message) throws IOException {
        FtpMessage ftpMessage = gson.fromJson(message, FtpMessage.class);
        ftpMessage = switch (ftpMessage.action) {
            case "connect" -> connectToFtp(session, ftpMessage);
            case "cd" -> handleFtpCd(session, ftpMessage);
            default -> null;
        };
        return gson.toJson(ftpMessage);
    }

    @OnOpen
    public void afterConnectionEstablished(Session session) {
        log.info("连接成功,{}", session.getId());
    }

    @OnClose
    public void afterConnectionClosed(Session session) {
        FTPUtil ftpUtil = ftpSessionManager.getSessionFtpClient(session.getId());
        if (ftpUtil != null) {
            ftpUtil.disconnect();
        }
        log.info("连接关闭");
    }

    @OnError
    public void handleWebSocketError(Session session, Throwable error) {
        ftpSessionManager.removeSessionFtpClient(session.getId());
        FTPUtil ftpUtil = ftpSessionManager.getSessionFtpClient(session.getId());
        if (ftpUtil != null) {
            ftpUtil.disconnect();
        }
        log.error("连接异常关闭：{}", error.getMessage());
    }
}